using System;
using Microsoft.Practices.Unity;

namespace Reactor.Client.ViewModel
{
    public interface IViewModelLocator
    {
        /// <summary>
        /// Gets the Main property which defines the main viewmodel.
        /// </summary>
        MainViewModel Main { get; }
        HomeViewModel Home { get; }
        ServicesViewModel Services { get; }
        AdoptServiceViewModel AdoptService { get; }
        OrphanConfirmationDialogViewModel OrphanService { get; }
        UpgradeDialogViewModel UpgradeService { get; }
    }

    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// </summary>
    public class ViewModelLocator : IViewModelLocator
    {
        /// <summary>
        /// Gets the Main property which defines the main viewmodel.
        /// </summary>
        public MainViewModel Main
        {
            get
            {
                return App.Container.Resolve<MainViewModel>();
            }
        }

        public HomeViewModel Home
        {
            get
            {
                return App.Container.Resolve<HomeViewModel>();
            }
        }

        public CoreViewModel Core
        {
            get { return App.Container.Resolve<CoreViewModel>(); }
        }

        public ServicesViewModel Services
        {
            get
            {
                var core = GetSelectedCoreViewModel();
                return App.Container.Resolve<ServicesViewModel>(new ParameterOverride("coreViewModel", core));
            }
        }

        public AdoptServiceViewModel AdoptService
        {
            get
            {
                var core = GetSelectedCoreViewModel();
                return App.Container.Resolve<AdoptServiceViewModel>(new ParameterOverride("coreViewModel", core));
            }
        }

        public OrphanConfirmationDialogViewModel OrphanService
        {
            get
            {
                var core = GetSelectedCoreViewModel();
                var service = GetSelectedServiceViewModel();

                return App.Container.Resolve<OrphanConfirmationDialogViewModel>(new ParameterOverride("coreViewModel", core), new ParameterOverride("serviceViewModel", service));
            }
        }

        public TransferDialogViewModel TransferService
        {
            get
            {
                var core = GetSelectedCoreViewModel();
                var service = GetSelectedServiceViewModel();

                return App.Container.Resolve<TransferDialogViewModel>(new ParameterOverride("coreViewModel", core), new ParameterOverride("serviceViewModel", service));
            }
        }

        public UpgradeDialogViewModel UpgradeService
        {
            get
            {
                var core = GetSelectedCoreViewModel();
                var service = GetSelectedServiceViewModel();

                return App.Container.Resolve<UpgradeDialogViewModel>(new ParameterOverride("coreViewModel", core), new ParameterOverride("serviceViewModel", service));
            }
        }

        private CoreViewModel GetSelectedCoreViewModel()
        {
            if (Home.SelectedCore == null) throw new InvalidOperationException("SelectedCore property of HomeViewModel cannot be null.");

            return Home.SelectedCore;
        }

        private ServiceViewModel GetSelectedServiceViewModel()
        {
            var selectedCore = GetSelectedCoreViewModel();
            if(selectedCore.SelectedService == null) throw new InvalidOperationException("SelectedService property of selected CoreViewModel cannot be null.");

            return selectedCore.SelectedService;
        }
    }
}